package com.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dao.NotificationDao;
import com.entity.IssueEntity;
import com.entity.NotificationEntity;
import com.model.Notification;
import com.model.SendingResult;
import com.service.status.StatusCode;

@Service
@Transactional
public class CollectMailService {

	private final String HELLO_MESSAGE = "Hello. This is Jira reporting system.";
	private final String NOTIFICATION = "You have unresolved assigned tickets: ";
	private final String TICKET_ID = " ID=";

	@Autowired
	TicketService ticketService;

	@Autowired
	NotificationDao notificationDao;

	public List<Notification> getMailingList(boolean groupByUser) {

		List<Notification> notificationList = new ArrayList<Notification>();
		List<IssueEntity> issues = ticketService
				.getIssuesByStatusCode(StatusCode.Open);

		for (int i = 0; i < issues.size(); ++i) {
			try {
				IssueEntity issue = issues.get(i);

				String email = issue.getFieldsEntity()
						.getUserEntityByIdAuthor().getEmailAddress();
				if (groupByUser) {
					Notification existingNotification = getNotificationByEmail(
							notificationList, email);
					if (existingNotification != null) {

						existingNotification.setMessage(existingNotification
														.getMessage()
														+ "\n"
														+ TICKET_ID
														+ issue.getId() + 
														";");

						Date previousAssignedDate = existingNotification
								.getAssignedDate();
						// TODO: updated date -> assigned date
						Date assignedDate = issue.getFieldsEntity().getUpdated();
						if (assignedDate.before(previousAssignedDate)) {
							existingNotification.setAssignedDate(assignedDate);
						}

						NotificationEntity previousLastNotification = notificationDao.getNotificationEntityByIssueId(existingNotification.getIssueId());

						NotificationEntity lastNotification = notificationDao.getNotificationEntityByIssueId(issue.getIdIssue());

						if (previousLastNotification != null) {
							if (lastNotification != null) {
								Date lastNotificationDate = lastNotification.getLastNotificationDate();
								Date existinglastNotificationDate = lastNotification.getLastNotificationDate();
								if (lastNotificationDate.before(existinglastNotificationDate)) {
									existingNotification.setLastNotification(lastNotificationDate);
								}
								SendingResult lastResult = getSendingResult(lastNotification);
								SendingResult existingLastResult = getSendingResult(previousLastNotification);
								if (lastResult != existingLastResult) {
									existingNotification.setNotificationResult(SendingResult.Partial);
								}
							} else {
								existingNotification.setLastNotification(null);
								existingNotification.setNotificationResult(SendingResult.Partial);
							}
						} else {
							existingNotification.setLastNotification(null);
							if (lastNotification !=  null) {
								existingNotification.setNotificationResult(SendingResult.Partial);
							} else {
								existingNotification.setNotificationResult(SendingResult.NotBeenSentBefore);
							}
						}
						existingNotification.setManyIssue(true);
						existingNotification.getIssuesId().add(issue.getIdIssue());
					} else {
						Notification notification = createNotification(notificationList, i, issue, email);
						notification.setManyIssue(true);
						notification.setIssuesId(new ArrayList<Integer>());
						notification.getIssuesId().add(issue.getIdIssue());
						notificationList.add(notification);
					}
				} else {
					Notification notification = createNotification(notificationList, i, issue, email);
					notification.setManyIssue(false);
					notificationList.add(notification);
				}
			} catch (NullPointerException e) {
				System.out.println("WARNING: NullPointerException");
			}
		}

		return notificationList;
	}

	private SendingResult getSendingResult(NotificationEntity lastNotification) {
		Boolean lastNotificationResult = lastNotification.getLastNotificationResult();
		SendingResult lastResult;
		if (lastNotificationResult == null) {
			lastResult = SendingResult.NotBeenSentBefore;
		} else if (lastNotificationResult) {
			lastResult = SendingResult.Succeed;
		} else {
			lastResult = SendingResult.Failed;
		}
		return lastResult;
	}

	private Notification createNotification(
			List<Notification> notificationList, int id, IssueEntity issue,	String email) {
		String message = HELLO_MESSAGE + "\n\n" + NOTIFICATION + "\n"
				+ TICKET_ID + issue.getId() + ";";

		// TODO: updated date -> assigned date
		Date assignedDate = issue.getFieldsEntity().getUpdated();

		NotificationEntity lastNotification = notificationDao
				.getNotificationEntityByIssueId(issue.getIdIssue());

		Notification notification;
		if (lastNotification != null) {
			Date lastNotificationDate = lastNotification.getLastNotificationDate();
			SendingResult lastResult = getSendingResult(lastNotification);
			notification = new Notification(id + 1, email, message,
					assignedDate, lastNotificationDate, lastResult,
					issue.getIdIssue());
		} else {
			notification = new Notification(id + 1, email, message,
					assignedDate, null, null, issue.getIdIssue());
		}
		return notification;
	}

	private Notification getNotificationByEmail(
			List<Notification> notificationList, String email) {
		for (Notification notification : notificationList) {
			if (email.equals(notification.getEmail())) {
				return notification;
			}
		}
		return null;

	}

}
